using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using JGSY.CMS.LowCode.Platform.Application.DTOs;
using JGSY.CMS.LowCode.Platform.Application.Interfaces;
using JGSY.CMS.LowCode.Platform.Infrastructure.Authorization;

namespace JGSY.CMS.LowCode.Platform.Controllers
{
    /// <summary>
    /// 权限路由映射管理控制器
    /// 提供路由映射的CRUD操作和集中管理功能
    /// </summary>
    [ApiController]
    [Route("api/[controller]")]
    [RequirePermission("system.permission.route.manage")]
    public class PermissionRouteMappingController : ControllerBase
    {
        private readonly IPermissionRouteMappingService _mappingService;

        public PermissionRouteMappingController(IPermissionRouteMappingService mappingService)
        {
            _mappingService = mappingService;
        }

        /// <summary>
        /// 获取所有活跃的路由映射
        /// </summary>
        [HttpGet]
        [RequirePermission("system.permission.route.read")]
        public async Task<ActionResult<IEnumerable<PermissionRouteMappingDto>>> GetActive()
        {
            var mappings = await _mappingService.GetActiveAsync();
            return Ok(mappings);
        }

        /// <summary>
        /// 分页获取路由映射
        /// </summary>
        [HttpGet("paged")]
        [RequirePermission("system.permission.route.read")]
        public async Task<ActionResult<object>> GetPaged(
            [FromQuery] int pageIndex = 1,
            [FromQuery] int pageSize = 20,
            [FromQuery] string? group = null,
            [FromQuery] bool? isActive = null,
            [FromQuery] string? search = null)
        {
            var (items, total) = await _mappingService.GetPagedAsync(pageIndex, pageSize, group, isActive, search);
            
            return Ok(new
            {
                items,
                total,
                pageIndex,
                pageSize,
                totalPages = (int)Math.Ceiling((double)total / pageSize)
            });
        }

        /// <summary>
        /// 根据ID获取路由映射
        /// </summary>
        [HttpGet("{id}")]
        [RequirePermission("system.permission.route.read")]
        public async Task<ActionResult<PermissionRouteMappingDto>> GetById(long id)
        {
            var mapping = await _mappingService.GetByIdAsync(id);
            if (mapping == null)
            {
                return NotFound($"Permission route mapping with ID {id} not found.");
            }
            return Ok(mapping);
        }

        /// <summary>
        /// 创建新的路由映射
        /// </summary>
        [HttpPost]
        [RequirePermission("system.permission.route.create")]
        public async Task<ActionResult<object>> Create([FromBody] PermissionRouteMappingDto dto)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            // 验证路径模式
            if (!_mappingService.ValidatePathPattern(dto.Path))
            {
                return BadRequest("Invalid path pattern. Pattern must start with '/' and use valid wildcard syntax.");
            }

            // 检查冲突
            if (await _mappingService.HasConflictAsync(dto.Path, dto.Method))
            {
                return Conflict($"Route mapping for path '{dto.Path}' and method '{dto.Method}' already exists.");
            }

            try
            {
                var id = await _mappingService.CreateAsync(dto);
                var created = await _mappingService.GetByIdAsync(id);
                
                return CreatedAtAction(nameof(GetById), new { id }, created);
            }
            catch (Exception ex)
            {
                return StatusCode(500, $"Failed to create route mapping: {ex.Message}");
            }
        }

        /// <summary>
        /// 更新路由映射
        /// </summary>
        [HttpPut("{id}")]
        [RequirePermission("system.permission.route.update")]
        public async Task<ActionResult> Update(long id, [FromBody] PermissionRouteMappingDto dto)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            var existing = await _mappingService.GetByIdAsync(id);
            if (existing == null)
            {
                return NotFound($"Permission route mapping with ID {id} not found.");
            }

            // 验证路径模式
            if (!_mappingService.ValidatePathPattern(dto.Path))
            {
                return BadRequest("Invalid path pattern. Pattern must start with '/' and use valid wildcard syntax.");
            }

            // 检查冲突（排除当前记录）
            if (await _mappingService.HasConflictAsync(dto.Path, dto.Method, id))
            {
                return Conflict($"Route mapping for path '{dto.Path}' and method '{dto.Method}' already exists.");
            }

            try
            {
                await _mappingService.UpdateAsync(id, dto);
                return NoContent();
            }
            catch (Exception ex)
            {
                return StatusCode(500, $"Failed to update route mapping: {ex.Message}");
            }
        }

        /// <summary>
        /// 删除路由映射
        /// </summary>
        [HttpDelete("{id}")]
        [RequirePermission("system.permission.route.delete")]
        public async Task<ActionResult> Delete(long id)
        {
            var existing = await _mappingService.GetByIdAsync(id);
            if (existing == null)
            {
                return NotFound($"Permission route mapping with ID {id} not found.");
            }

            try
            {
                await _mappingService.DeleteAsync(id);
                return NoContent();
            }
            catch (Exception ex)
            {
                return StatusCode(500, $"Failed to delete route mapping: {ex.Message}");
            }
        }

        /// <summary>
        /// 批量删除路由映射
        /// </summary>
        [HttpDelete("batch")]
        [RequirePermission("system.permission.route.delete")]
        public async Task<ActionResult> BatchDelete([FromBody] IEnumerable<long> ids)
        {
            if (ids == null || !ids.Any())
            {
                return BadRequest("IDs list cannot be empty.");
            }

            try
            {
                await _mappingService.BatchDeleteAsync(ids);
                return NoContent();
            }
            catch (Exception ex)
            {
                return StatusCode(500, $"Failed to batch delete route mappings: {ex.Message}");
            }
        }

        /// <summary>
        /// 解析权限码
        /// </summary>
        [HttpGet("resolve")]
        [RequirePermission("system.permission.route.read")]
        public async Task<ActionResult<object>> ResolvePermission([FromQuery] string path, [FromQuery] string method)
        {
            if (string.IsNullOrEmpty(path) || string.IsNullOrEmpty(method))
            {
                return BadRequest("Path and method are required.");
            }

            var permissionCode = await _mappingService.ResolvePermissionAsync(path, method);
            
            return Ok(new
            {
                path,
                method,
                permissionCode,
                resolved = !string.IsNullOrEmpty(permissionCode)
            });
        }

        /// <summary>
        /// 批量解析权限码
        /// </summary>
        [HttpPost("resolve/batch")]
        [RequirePermission("system.permission.route.read")]
        public async Task<ActionResult<Dictionary<string, string>>> BatchResolvePermissions(
            [FromBody] IEnumerable<RouteRequest> requests)
        {
            if (requests == null || !requests.Any())
            {
                return BadRequest("Requests list cannot be empty.");
            }

            var tuples = requests.Select(r => (r.Path, r.Method));
            var results = await _mappingService.BatchResolvePermissionsAsync(tuples);
            
            return Ok(results);
        }

        /// <summary>
        /// 获取所有分组
        /// </summary>
        [HttpGet("groups")]
        [RequirePermission("system.permission.route.read")]
        public async Task<ActionResult<IEnumerable<string>>> GetGroups()
        {
            var groups = await _mappingService.GetGroupsAsync();
            return Ok(groups);
        }

        /// <summary>
        /// 测试路径匹配
        /// </summary>
        [HttpGet("test-match")]
        [RequirePermission("system.permission.route.read")]
        public async Task<ActionResult<IEnumerable<PermissionRouteMappingDto>>> TestMatch(
            [FromQuery] string path, [FromQuery] string method)
        {
            if (string.IsNullOrEmpty(path) || string.IsNullOrEmpty(method))
            {
                return BadRequest("Path and method are required.");
            }

            var matches = await _mappingService.TestMatchAsync(path, method);
            return Ok(matches);
        }

        /// <summary>
        /// 从配置导入路由映射
        /// </summary>
        [HttpPost("import/config")]
        [RequirePermission("system.permission.route.import")]
        public async Task<ActionResult<object>> ImportFromConfiguration([FromQuery] bool replaceExisting = false)
        {
            try
            {
                var imported = await _mappingService.ImportFromConfigurationAsync(replaceExisting);
                
                return Ok(new
                {
                    imported,
                    replaceExisting,
                    timestamp = DateTime.UtcNow
                });
            }
            catch (Exception ex)
            {
                return StatusCode(500, $"Failed to import from configuration: {ex.Message}");
            }
        }

        /// <summary>
        /// 导出路由映射为JSON
        /// </summary>
        [HttpGet("export")]
        [RequirePermission("system.permission.route.export")]
        public async Task<ActionResult> ExportAsJson([FromQuery] string? group = null)
        {
            try
            {
                var json = await _mappingService.ExportAsJsonAsync(group);
                var fileName = $"route-mappings-{DateTime.UtcNow:yyyyMMdd-HHmmss}";
                if (!string.IsNullOrEmpty(group))
                {
                    fileName += $"-{group}";
                }
                fileName += ".json";
                
                return File(System.Text.Encoding.UTF8.GetBytes(json), "application/json", fileName);
            }
            catch (Exception ex)
            {
                return StatusCode(500, $"Failed to export route mappings: {ex.Message}");
            }
        }

        /// <summary>
        /// 从JSON导入路由映射
        /// </summary>
        [HttpPost("import/json")]
        [RequirePermission("system.permission.route.import")]
        public async Task<ActionResult<object>> ImportFromJson(
            [FromForm] string json,
            [FromQuery] bool replaceExisting = false)
        {
            if (string.IsNullOrEmpty(json))
            {
                return BadRequest("JSON data is required.");
            }

            try
            {
                var imported = await _mappingService.ImportFromJsonAsync(json, replaceExisting);
                
                return Ok(new
                {
                    imported,
                    replaceExisting,
                    timestamp = DateTime.UtcNow
                });
            }
            catch (Exception ex)
            {
                return StatusCode(500, $"Failed to import from JSON: {ex.Message}");
            }
        }

        /// <summary>
        /// 获取统计信息
        /// </summary>
        [HttpGet("statistics")]
        [RequirePermission("system.permission.route.read")]
        public async Task<ActionResult<PermissionRouteMappingStatisticsDto>> GetStatistics()
        {
            var statistics = await _mappingService.GetStatisticsAsync();
            return Ok(statistics);
        }

        /// <summary>
        /// 刷新缓存
        /// </summary>
        [HttpPost("cache/refresh")]
        [RequirePermission("system.permission.route.manage")]
        public async Task<ActionResult> RefreshCache()
        {
            try
            {
                await _mappingService.RefreshCacheAsync();
                return Ok(new { message = "Cache refreshed successfully", timestamp = DateTime.UtcNow });
            }
            catch (Exception ex)
            {
                return StatusCode(500, $"Failed to refresh cache: {ex.Message}");
            }
        }
    }

    /// <summary>
    /// 路由请求DTO
    /// </summary>
    public class RouteRequest
    {
        public string Path { get; set; } = string.Empty;
        public string Method { get; set; } = string.Empty;
    }
}
